package cn.tedu.charging.order.config;

import cn.tedu.charging.order.mqtt.MqttConsumer;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 连接消息中间件 EMQX的 配置类
 * 连接EMQX的目的是为了和设备通信
 * 能给设备发消息
 * 能接收设备发来的消息
 */
@Slf4j
@Configuration
public class MqttConfiguration {
    /**
     * 连接地址 tcp 协议 1883 端口号
     * 配置信息 应该 放到配置文件 或者放到 配置中心 nacos
     */
    private String host = "tcp://127.0.0.1:1883";

    /**
     * 用户名
     * 配置信息 应该 放到配置文件 或者放到 配置中心 nacos
     */
    private String userName = "admin";

    /**
     * 密码
     * 配置信息 应该 放到配置文件 或者放到 配置中心 nacos
     */
    private String password = "public";

    /**
     * 客户端ID
     * 相同的id EMQX 不允许同时连接 不能同时在线
     * 为了让多个订单服务 同时能连接上EMQX ，
     * 给每个订单服务都分配一个不同的客户端ID 用随机数来实现
     */
    private String clientId = "order_service_client" + Math.random();

    /**
     * 通过 @Bean注解，创建MqttClient 对象并且交给spring容器管理
     * 别的 在容器中的类 可以通过注入的方式 使用 MqttClient
     */
    @Bean
    public MqttClient mqttClient() throws Exception{
        //通过 连接地址 和 客户端id创建 MqttClient 对象
        MqttClient mqttClient = new MqttClient(host, clientId);
        // 创建 MqttConnectOptions 连接相关的配置
        MqttConnectOptions options = new MqttConnectOptions();
        //配置用户名
        options.setUserName(userName);
        //配置密码 char[] 字符串转成字符数组 password.toCharArray()
        // 把 字符串 转换为 字符数组
        //字符串常用的方法 大家得关注 String
        options.setPassword(password.toCharArray());

        //options 有很多其他的配置 可以自己了解
    /*  options.setCleanSession(true);
        options.setKeepAliveInterval(60);
        options.setConnectionTimeout(30);
        options.setMaxInflight(100);
        options.setAutomaticReconnect(true);
        options.setExecutorServiceTimeout(1000);
  */
        /**
         * MqttConsumer mqttConsumer = new MqttConsumer()
         * mqttConsumer 通过java 语法new 出来的 没有在spring容器中管理
         * MqttClient @Bean 创建的 在容器中的
         * mqttClient.setCallback 来配置callback 回调方法
         */
        /**
         * mqttConsumer 没有在容器中 想要使用容器中的mqttClient该如何处理？
         * 1 构造器 把mqttClient 传入到 mqttConsumer
         */
        MqttConsumer mqttConsumer = new MqttConsumer(mqttClient);
        /**
         * mqttConsumer 没有在容器中 想要使用容器中的mqttClient改如何处理？
         * 2 setter 方法
         * mqttConsumer.setMqttClient(mqttClient);
         */
        mqttClient.setCallback(mqttConsumer);
        // 通过配置信息 options 连接emqx
        mqttClient.connect(options);
        log.debug("创建客户端成功");
        return mqttClient;
    }
}
